/**
 * 
 */
package jsr292.weaver;

import java.util.HashMap;

import org.objectweb.asm.Type;

public class Wrapper {
  public final String wrapperClassName;
  public final String unboxingMethodName;
  public final String unboxingDesc;
  public final String boxingDesc;
  public final Class<?> primitiveClass;

  private Wrapper(String wrapperClassName, String unboxingMethodName,
      String unboxingDesc, String boxingDesc, Class<?> primitiveClass) {
    this.wrapperClassName = wrapperClassName;
    this.unboxingMethodName = unboxingMethodName;
    this.unboxingDesc = unboxingDesc;
    this.boxingDesc = boxingDesc;
    this.primitiveClass = primitiveClass;
  }
  
  /**
   * @param wrapperOrPrimitiveClass a wrapper class (e.g java.lang.Integer) or
   *        a primitive class (e.g char).
   * @return a wrapper
   */
  public static Wrapper getWrapper(Class<?> wrapperOrPrimitiveClass) {
    return WRAPPER_MAP.get(wrapperOrPrimitiveClass.getName());
  }
  
  public static final Wrapper[] WRAPPERS;
  private static final HashMap<String, Wrapper> WRAPPER_MAP;
  static {
    Wrapper[] array = new Wrapper[11];  
    array[Type.BOOLEAN] = new Wrapper("java/lang/Boolean",   "booleanValue", "()Z", "(Z)Ljava/lang/Boolean;",   boolean.class);
    array[Type.BYTE] =    new Wrapper("java/lang/Byte",      "byteValue",    "()B", "(B)Ljava/lang/Byte;",      byte.class);
    array[Type.SHORT] =   new Wrapper("java/lang/Short",     "shortValue",   "()S", "(S)Ljava/lang/Short;",     short.class);
    array[Type.CHAR] =    new Wrapper("java/lang/Character", "charValue",    "()C", "(C)Ljava/lang/Character;", char.class);
    array[Type.INT] =     new Wrapper("java/lang/Integer",   "intValue",     "()I", "(I)Ljava/lang/Integer;",   int.class);
    array[Type.LONG] =    new Wrapper("java/lang/Long",      "longValue",    "()J", "(J)Ljava/lang/Long;",      long.class);
    array[Type.FLOAT] =   new Wrapper("java/lang/Float",     "floatValue",   "()F", "(F)Ljava/lang/Float;",     float.class);
    array[Type.DOUBLE] =  new Wrapper("java/lang/Double",    "doubleValue",  "()D", "(D)Ljava/lang/Double;",    double.class);
    // wrappers[Type.ARRAY] = null;
    // wrappers[Type.OBJECT] = null;
    WRAPPERS = array;
    
    HashMap<String, Wrapper> map = new HashMap<String, Wrapper>();
    for(Wrapper wrapper:array) {
      if (wrapper==null)
        continue;
      map.put(wrapper.wrapperClassName.replace('/', '.'), wrapper);
      map.put(wrapper.primitiveClass.getName(), wrapper);
    }
    WRAPPER_MAP = map;
  }
}